package com.boe.hbd.client.activity;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import com.boe.hbd.client.R;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.TextView;

public class ImageAdapter extends BaseAdapter {
	private int width  = -1;
	private int height = -1;
	
    private int[] mTo;
    private String[] mFrom; 

    private List<? extends Map<String, ?>> mData;

    private int mResource; 
    private LayoutInflater mInflater;
    private final WeakHashMap<View, View[]> mHolders = new WeakHashMap<View, View[]>();
	
	private Activity mActivity      = null;
	private Map<String,Object> thumbCached = new HashMap<String,Object>();

	public ImageAdapter(Activity activity, List<? extends Map<String, ?>> data,
			int resource, String[] from, int[] to) {
		mActivity = activity;
		mData     = data;
		mResource = resource;
		mFrom     = from;
		mTo       = to;
		mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
 
    public int getCount() {
        return mData.size();
    }
 
    public Object getItem(int position) {
        return mData.get(position);
    }
 
    public long getItemId(int position) {
        return position;
    }
 
    public View getView(int position, View convertView, ViewGroup parent) {
        return createViewFromResource(position, convertView, parent, mResource);
    }

    private View createViewFromResource(int position, View convertView,ViewGroup parent, int resource) {
        View v;
        if (convertView == null) {
            v = mInflater.inflate(resource, parent, false);
            final int[] to  = mTo;
            final int count = to.length;
            final View[] holder = new View[count];            
            for (int i = 0; i < count; i++) {
                holder[i] = v.findViewById(to[i]);
                if (holder[i] instanceof ImageView ) {
                	ImageView iv = (ImageView)holder[i];
        			LayoutParams params = iv.getLayoutParams();
        			if (width >= 0 && params.width != width) {
        				params.width = width; 
        			}
        			if (height >= 0 && params.height != height) {
        				params.height = height; 
        			}  
        			iv.setLayoutParams(params);
                }
            }
            mHolders.put(v, holder);
        } else {
            v = convertView;
        }
        bindView(position, v);
        return v;
    }

    private void bindView(int position, View view) {
        final Map<String,?> dataSet = mData.get(position);
        if (dataSet == null) {
            return;
        }
 
        final View[] holder = mHolders.get(view);
        final String[] from = mFrom;
        final int[] to = mTo;
        final int count = to.length;

        for (int i = 0; i < count; i++) {
            final View v = holder[i];
            if (v != null) {
                final Object data = dataSet.get(from[i]);
                String text = data == null ? "" : data.toString();
                if (text == null) {
                    text = "";
                }  
                if (v instanceof Checkable) {
                    if (data instanceof Boolean) {
                        ((Checkable) v).setChecked((Boolean) data);
                    } else {
                        throw new IllegalStateException(v.getClass().getName() + " should be bound to a Boolean, not a " + data.getClass());
                    }
                } else if (v instanceof TextView) {
                    setViewText((TextView) v, text);
                } else if (v instanceof ImageView) {
                    if (data instanceof Integer) {
                        setViewImage((ImageView) v, (Integer) data);                            
                    } else {
                        setViewImage((ImageView) v, text);
                    }
                } else {
                    throw new IllegalStateException(v.getClass().getName() + " is not a view that can be bounds by this SimpleAdapter");
                } 
            }
        }
    }
 
    public void setViewImage(ImageView v, int value) {
        v.setImageResource(value);
    }

    public void setViewImage(final ImageView v, String uriOfImage) {
    	if (!thumbCached.containsKey(uriOfImage)) {
    		// STEP 1: find the path of image
			Cursor imgCursor   = mActivity.getContentResolver().query(Uri.parse(uriOfImage), new String[] { Media._ID,Media.DATA } , null, null, null);
			if (imgCursor.moveToFirst()) {
				String imageId     = imgCursor.getString(imgCursor.getColumnIndexOrThrow(Media._ID));
				// STEP 2: find the path of thumb
				if (imageId != null) {
					Cursor thumbCursor = mActivity.getContentResolver().query(
							Thumbnails.EXTERNAL_CONTENT_URI, new String[] { Thumbnails._ID , Thumbnails.DATA } , Thumbnails.IMAGE_ID + "=?" , new String[]{imageId}, null);
					if (thumbCursor != null && thumbCursor.moveToFirst()) {
						String pathOfThumb = thumbCursor.getString(thumbCursor.getColumnIndexOrThrow(Thumbnails.DATA));
						if ( new File(pathOfThumb).exists() ) {
							thumbCached.put(uriOfImage, pathOfThumb);
						}
					} 
					if (!thumbCached.containsKey(uriOfImage)) {
						Bitmap thumb = Thumbnails.getThumbnail(mActivity.getContentResolver(), Integer.valueOf(imageId), Thumbnails.MINI_KIND, null);
						thumbCached.put(uriOfImage, thumb);
					}
				} else {
					thumbCached.put(uriOfImage, null);
				}
			}
    	}
    	Object cachedObj = thumbCached.get(uriOfImage);
    	if (cachedObj != null) {
    		if (cachedObj instanceof String) {
    			v.setImageURI(Uri.parse(cachedObj.toString()));
    		} else {
    			v.setImageBitmap((Bitmap)cachedObj);
    		}
    	} else {
    		v.setImageResource(R.drawable.image_for_empty_url);
    	}
    }

    public void setViewText(TextView v, String text) {
        v.setText(text);
    }
    
	public void refreshLayoutParams(int width, int height) {
		this.width = width;
		this.height = height; 
		thumbCached.clear();
	}
}
